package com.example.doctor.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.example.common.entity.*;
import com.example.common.support.ApiException;
import com.example.common.utils.IdUtils;
import com.example.doctor.dto.req.*;
import com.example.doctor.dto.resp.*;
import com.example.doctor.jpa.*;
import com.example.doctor.mapper.GroupPatientsMapper;
import com.example.doctor.mapper.OrderMainMapper;
import com.example.doctor.mapper.PatientMapper;
import com.example.doctor.mapper.RxOrderMapper;
import com.example.doctor.service.PatientService;
import com.example.doctor.utils.UserUtils;
import com.github.pagehelper.ISelect;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.core.CollectionUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author sifan
 * @PackagName:com.example.doctor.service.impl
 * @ClassName: PatientServiceImpl
 * @Description:
 * @date:2021/1/19 19:14
 */
@Service
@Slf4j
public class PatientServiceImpl implements PatientService {


    @Resource
    DoctorGroupMainRepository doctorGroupMainRepository;

    @Resource
    DoctorGroupPatientsrRepository doctorGroupPatientsrRepository;

    @Resource
    GroupPatientsMapper groupPatientsMapper;

    @Resource
    UserUtils userUtils;

    @Resource
    PatientMapper patientMapper;

    @Resource
    OrderMainRepository orderMainRepository;

    @Resource
    PatientsInfoRepository patientsInfoRepository;

    @Resource
    DoctorBaseInfoRepository doctorBaseInfoRepository;

    @Resource
    RxMainRepository rxMainRepository;

    @Resource
    HospitalDepartmentRepository hospitalDepartmentRepository;

    @Resource
    RxInfoRepository rxInfoRepository;

    @Resource
    RxDrugsRepository rxDrugsRepository;

    @Resource
    ImgRepository imgRepository;

    @Resource
    ClientPatientsInfoRepository clientPatientsInfoRepository;
    @Resource
    RxOrderMapper rxOrderMapper;


    @Override
    public List<GroupListRsp> GroupList() {
        List<GroupListRsp> groupListRsps = new ArrayList<>();
        Long dcid = userUtils.getUser().getDcId();
        List<DoctorGroupMain> doctorGroupMains = doctorGroupMainRepository.findByDcId(dcid);
        for (DoctorGroupMain doctorGroupMain : doctorGroupMains) {
            GroupListRsp groupListRsp = new GroupListRsp();
            Integer count = doctorGroupPatientsrRepository.findByDcIdAndCount(doctorGroupMain.getGid());
            groupListRsp.setGroupName(doctorGroupMain.getGroupName());
            groupListRsp.setGID(doctorGroupMain.getGid());
            groupListRsp.setPCount(count);
            groupListRsps.add(groupListRsp);
        }
        GroupListRsp groupListRsp = new GroupListRsp();
        groupListRsp.setGID(0l);
        groupListRsp.setGroupName("全部患者");
        groupListRsp.setPCount(doctorGroupPatientsrRepository.findCountAllByDcId(dcid));
        groupListRsps.add(groupListRsp);
        return groupListRsps;
    }

    @Override
    public Map<String,Object> GroupPatients(GroupPatientsReq groupPatientsReq) {
        Map<String,Object> result=new HashMap<>();
        long GID = groupPatientsReq.getGID();
        Boolean IsAll = groupPatientsReq.getIsAll();
        String Search = groupPatientsReq.getSearch();
        long dcid = userUtils.getUser().getDcId();
        List<GroupPatientsDb> list = new ArrayList<>();
        long count=0;
        if(GID != 0){
            list = groupPatientsMapper.queryByGID(GID,dcid,Search,(groupPatientsReq.getPageNum()-1)*groupPatientsReq.getPageSize(),groupPatientsReq.getPageSize());
            count = groupPatientsMapper.countByGID(GID, dcid, Search);
            for (GroupPatientsDb groupPatientsDb : list) {
                if (!ObjectUtils.isEmpty(groupPatientsDb.getBirthday())) {
                    groupPatientsDb.setAge(DateUtil.betweenYear(groupPatientsDb.getBirthday(), new Date(), false));
                }
            }
        }else{
            String gpids = "";
            if(!IsAll){
                 List<String> gpid = groupPatientsMapper.queryInGroupByDCID(dcid);
                 if(gpid != null && gpid.size() > 0)
                    gpids = String.join(",", gpid);
            }
           count=groupPatientsMapper.countAllByGID(dcid, IsAll,gpids,Search);
            list = groupPatientsMapper.queryAllByGID(dcid, IsAll,gpids,Search,(groupPatientsReq.getPageNum()-1)*groupPatientsReq.getPageSize(),groupPatientsReq.getPageSize());
            for (GroupPatientsDb groupPatientsDb : list) {
                if (!ObjectUtils.isEmpty(groupPatientsDb.getBirthday())) {
                    groupPatientsDb.setAge(DateUtil.betweenYear(groupPatientsDb.getBirthday(), new Date(), false));
                }
            }
        }
        result.put("total",count);
        result.put("list",list);
        return result;
    }

    @Override
    public PageInfo<GroupPatientsDb> NoInGroupPatients(GroupPatientsReq groupPatientsReq) {

        //分组中的患者
        List<Long> pids = new ArrayList<>();
        long[] groupPatientsDbs = groupPatientsMapper.GroupPatients(groupPatientsReq.getGID());
        if(groupPatientsDbs != null && groupPatientsDbs.length > 0){
            for (long groupPatientsDb : groupPatientsDbs) {
                pids.add(groupPatientsDb);
            }
        }

        //查出所有患者排除分组中的
        PageInfo<GroupPatientsDb> objectPageInfo = PageHelper.startPage(groupPatientsReq.getPageNum(), groupPatientsReq.getPageSize()).doSelectPageInfo(() -> groupPatientsMapper.queryByDcId(userUtils.getUser().getDcId(), pids, groupPatientsReq.getSearch()));
        List<GroupPatientsDb> groupPatientsDbList = objectPageInfo.getList();
        for (GroupPatientsDb groupPatientsDb : groupPatientsDbList) {
            if (!ObjectUtils.isEmpty(groupPatientsDb.getBirthday())) {
                groupPatientsDb.setAge(DateUtil.betweenYear(groupPatientsDb.getBirthday(), new Date(), false));
            }
        }
        return objectPageInfo;
    }

    @Override
    public HashMap<String, Object> EditGroupName(EditGroupNameReq editGroupNameReq) {
        DoctorGroupMain doctorGroupMain = doctorGroupMainRepository.findById(editGroupNameReq.getGID()).orElse(null);
        doctorGroupMain.setGroupName(editGroupNameReq.getName());
        doctorGroupMainRepository.save(doctorGroupMain);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("UpSess", true);
        return hashMap;
    }

    @Override
    public HashMap<String, Object> AddGroup(AddGroupReq addGroupReq) {
        DoctorGroupMain doctorGroupMain = new DoctorGroupMain();
        doctorGroupMain.setGid(IdUtils.generateId());
        doctorGroupMain.setCreateTime(new Date());
        doctorGroupMain.setDcId(userUtils.getUser().getDcId());
        doctorGroupMain.setGroupName(addGroupReq.getName());
        doctorGroupMainRepository.save(doctorGroupMain);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("Gid", doctorGroupMain.getGid());
        hashMap.put("UpSess", true);
        return hashMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "jpaTransactionManager")
    public HashMap<String, Object> DelGroup(DelGroupReq delGroupReq) {
        if (0l == delGroupReq.getGID()) {
            throw new ApiException(400, "不能删除");
        }
        doctorGroupMainRepository.deleteById(delGroupReq.getGID());
        doctorGroupPatientsrRepository.deleteByGid(delGroupReq.getGID());
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("UpSess", true);
        return hashMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "jpaTransactionManager")
    public HashMap<String, Object> EditGroup(EditGroupReq editGroupReq) {
        //移除组
        if (!ObjectUtils.isEmpty(editGroupReq.getDelPids())) {
            String[] split = editGroupReq.getDelPids().split(",");
            for (String pid : split) {
                List<DoctorGroupPatients> list =  doctorGroupPatientsrRepository.findAllByPidAndGid(Long.valueOf(pid),editGroupReq.getGID());
                if(!list.isEmpty()){
                    doctorGroupPatientsrRepository.deleteAll(list);
                }
            }
        }
        //添加组
        if (!ObjectUtils.isEmpty(editGroupReq.getPids())) {
            String[] split = editGroupReq.getPids().split(",");
            for (String pid : split) {
                List<DoctorGroupPatients> romlist =  doctorGroupPatientsrRepository.findAllByPidOtherGid(editGroupReq.getGID(), Long.valueOf(pid));
                if(!romlist.isEmpty()){
                    doctorGroupPatientsrRepository.deleteAll(romlist);
                }
                List<DoctorGroupPatients> list =  doctorGroupPatientsrRepository.findAllByPidAndGid(Long.valueOf(pid),editGroupReq.getGID());
                if(!list.isEmpty()){
                    continue;
                }
                DoctorGroupPatients doctorGroupPatients = new DoctorGroupPatients();
                doctorGroupPatients.setId(IdUtils.generateId());
                doctorGroupPatients.setGid(editGroupReq.getGID());
                doctorGroupPatients.setPid(Long.valueOf(pid).longValue());
                doctorGroupPatientsrRepository.save(doctorGroupPatients);
            }
        }
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("UpSess", true);
        return hashMap;
    }

    @Override
    public HashMap<String, Object> PatientInfo(PatientInfoReq patientInfoReq) {
        long pid = patientInfoReq.getPID();
        long dcid = userUtils.getUser().getDcId();

        SimpleDateFormat fdate = new SimpleDateFormat("yyyy.MM.dd");

        String GroupName = patientMapper.getGroupName(pid, dcid);
        if(GroupName == null || GroupName.isEmpty())
            GroupName = "未分组";

        ClientPatientsInfo patient = clientPatientsInfoRepository.findById(pid).orElseThrow(() -> new ApiException(1, "没有患者信息"));
        Map<String, Object> p = new HashMap<>();
        p.put("Header", patient.getHeader());
        p.put("Name", patient.getName());
        p.put("Sex", patient.getSex());
        p.put("Age", DateUtil.betweenYear(patient.getBirthday(), new Date(), Boolean.FALSE));
        p.put("GroupName", GroupName);

        Map<String, Object> RxInfo = null;
        RxMain Rx = rxMainRepository.findByLastOne(pid);
        if(Rx != null){
            List<Map<String, Object>> zRx = null;
            List<Map<String, Object>> xRx = null;
            if(Rx.getDType() == 1){
                zRx = rxOrderMapper.selectzRxInfoList(Rx.getRxOrderNO());
            }
            if(Rx.getDType() == 2||Rx.getDType()==3){
                xRx = rxOrderMapper.selectxRxInfoList(Rx.getRxOrderNO());
            }

            RxInfo = new HashMap<>();
            RxInfo.put("CreateTime", fdate.format(Rx.getCreateTime()));
            RxInfo.put("Dialectical", Rx.getDialectical());
            RxInfo.put("ZRx", zRx);
            RxInfo.put("xRx", xRx);
        } 

        Map<String, Object> ParInfo = null;
        Map<String, Object> pat = rxOrderMapper.selectLastOrder(pid);
        if(pat != null){
            DoctorBaseInfo doctor = doctorBaseInfoRepository.findByDcId(Long.valueOf(pat.get("dc_id_bigint").toString()));
            HospitalDepartment depart = hospitalDepartmentRepository.findById(doctor.getDepartId()).orElse(null);
            RxMain rxMain = rxMainRepository.findLastOrder(pat.get("order_no_nvarchar").toString());

            ParInfo = new HashMap<>();
            ParInfo.put("Allergy", pat.get("allergy_nvarchar"));
            ParInfo.put("PastDisease", pat.get("past_disease_nvarchar"));
            ParInfo.put("ReceiveTime", fdate.format((Date)pat.get("receive_time_datetime")));
            ParInfo.put("Name", doctor.getName());
            ParInfo.put("dName", depart.getName());
            ParInfo.put("Title", doctor.getTitle());
            ParInfo.put("Dialectical", rxMain != null ? rxMain.getDialectical() : "");
        }


        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("Patient", p);
        hashMap.put("Rx", RxInfo);
        hashMap.put("Par", ParInfo);
        return hashMap;
    }

    
    @Override
    public List<Map<String, Object>> PRxList(int page, int limit, long PID){
        int skip = (page - 1) * limit;
        if (skip < 0) skip = 0;
        limit = Integer.MAX_VALUE / 10000;
        List<Map<String, Object>> list = rxOrderMapper.RxList(0, PID, "1,2,3", skip, limit);
        if(list != null && list.size() == 0)
            return null;

        List<String> olist = list.stream().filter(m -> m.get("DType").toString().equals("3") || m.get("DType").toString().equals("2")).map(e -> e.get("RxOrderNO").toString()).collect(Collectors.toList());
        String RxOrderNOs = "'" + String.join("','", olist) + "'";
        List<Map<String, Object>> drugList = rxOrderMapper.RxDrugList(RxOrderNOs); 

        list.forEach(m -> {
            if(m.get("DType").toString().equals("3") || m.get("DType").toString().equals("2"))
                m.put("Drug", drugList.stream().filter(n -> n.get("RxOrderNO").toString().equals(m.get("RxOrderNO").toString()))
                .collect(Collectors.toList()));
        });

        return list;
    }

    @Override
    public PageInfo<xRxListRsp> xRxList(xRxListReq xRxListReq) {
        PageInfo<xRxListRsp> objectPageInfo = PageHelper.startPage(xRxListReq.getPage(), xRxListReq.getLimit()).doSelectPageInfo(() -> patientMapper.queryByPid(xRxListReq.getPID()));
        List<xRxListRsp> list = objectPageInfo.getList();
        for (xRxListRsp xRxListRsp : list) {
            List<Drug> drugs = patientMapper.queryByRxOrderNO(xRxListRsp.getRxOrderNO());
            xRxListRsp.setDrug(drugs);
        }
        return new PageInfo<>(list);
    }

    @Override
    public PageInfo<zRxListRsp> zRxList(xRxListReq xRxListReq) {
        PageInfo<zRxListRsp> objectPageInfo = PageHelper.startPage(xRxListReq.getPage(), xRxListReq.getLimit()).doSelectPageInfo(() -> patientMapper.queryByRxOrderNOz(xRxListReq.getPID()));
        List<zRxListRsp> list = objectPageInfo.getList();
        List<String> olist = list.stream().filter(m -> m.getDType().equals("3") ).map(e -> e.getRxOrderNO()).collect(Collectors.toList());
        String RxOrderNOs = "'" + String.join("','", olist) + "'";
        List<Map<String, Object>> drugList = rxOrderMapper.RxDrugList(RxOrderNOs);
        list = list.stream().peek(m -> {
            if (m.getDType().equals("3"))
                m.setDrug(drugList.stream().filter(n -> n.get("RxOrderNO").equals(m.getRxOrderNO()))
                        .peek(x->{
                                log.info(x.toString());
                                x.put("Suggest",x.get("med_way_nvarchar")+";"+x.get("freq_nvarchar")+";"+x.get("day_int")+"天;");})
                        .collect(Collectors.toList()));
        }).collect(Collectors.toList());
        return objectPageInfo;
    }

    @Override
    public PageInfo<DiagnosisListRsp> DiagnosisList(xRxListReq xRxListReq) {
        DateTime dateTime = DateUtil.offsetMonth(new Date(), -6);
        PageInfo<DiagnosisListRsp> objectPageInfo = PageHelper.startPage(xRxListReq.getPage(), xRxListReq.getLimit()).doSelectPageInfo(() -> patientMapper.queryDiagnosisListByPid(xRxListReq.getPID(), dateTime));
        List<DiagnosisListRsp> diagnosisListRspList = objectPageInfo.getList();
        for (DiagnosisListRsp diagnosisListRsp : diagnosisListRspList) {
            List<RxMain> rxMainList = rxMainRepository.findByOrderNOAndIsTrialPharmCa(diagnosisListRsp.getOrderNO(),true);
            diagnosisListRsp.setDisease(String.join("、", rxMainList.stream().map(RxMain::getDialectical).collect(Collectors.toList())));
        }
        return objectPageInfo;
    }

    @Override
    public HashMap<String, Object> DiagnosisIn(DiagnosisInReq diagnosisInReq) {
        DiagnosisInRsp diagnosisInReqList = patientMapper.DiagnosisIn(diagnosisInReq.getOrderNO());
        List<RxMain> rxMainList = rxMainRepository.findByOrderNOAndSystem(diagnosisInReq.getOrderNO());
        diagnosisInReqList.setDialecticals(String.join("、", rxMainList.stream().map(RxMain::getDialectical).collect(Collectors.toList())));
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("detail", diagnosisInReqList);
        return hashMap;
    }

    @Override
    public HashMap<String, Object> DiagnosisOut(DiagnosisInReq diagnosisInReq) {
        DiagnosisOutRsp diagnosisOutRsp = patientMapper.DiagnosisOut(diagnosisInReq.getOrderNO());
        switch (diagnosisOutRsp.getFirstType()) {
            case 1:
                diagnosisOutRsp.setFirstTypeName("本院本医生");
                break;
            case 2:
                diagnosisOutRsp.setFirstTypeName("非本院复诊");
                break;
            case 3:
                diagnosisOutRsp.setFirstTypeName("本院其他医生");
                break;
        
            default:
                break;
        }
        List<RxMain> rxMainList = rxMainRepository.findByOrderNOAndSystem(diagnosisInReq.getOrderNO());
        List<Img> imgList = imgRepository.findByPatientsInfoId(diagnosisOutRsp.getID());
        diagnosisOutRsp.setDialecticals(String.join("、", rxMainList.stream().map(RxMain::getDialectical).collect(Collectors.toList())));
        Object[] objects =  imgList.stream().map(Img::getImg).toArray();
        diagnosisOutRsp.setImgs(objects);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("detail", diagnosisOutRsp);
        return hashMap;
    }
}
